package cn.lingyangwl.agile.pay.pay.channel;

import cn.lingyangwl.framework.tool.core.exception.Assert;
import cn.lingyangwl.agile.model.constants.ServiceCodeCons;
import cn.lingyangwl.agile.pay.common.constants.Cs;
import cn.lingyangwl.agile.pay.constant.IfCodeEnum;
import cn.lingyangwl.agile.pay.constant.PayWayCodeEnum;
import cn.lingyangwl.agile.pay.model.entity.PayOrder;
import cn.lingyangwl.agile.pay.common.service.PaySysConfigService;
import cn.lingyangwl.agile.pay.common.utils.ChannelCertConfigKitBean;
import cn.lingyangwl.agile.pay.pay.service.ConfigContextQueryService;
import lombok.extern.slf4j.Slf4j;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 支付接口抽象类
 *
 * @author shenguangyang
 */
@Slf4j
public abstract class AbstractPaymentService implements IPaymentService {

    @Resource
    protected PaySysConfigService paySysConfigService;
    @Resource
    protected ChannelCertConfigKitBean channelCertConfigKitBean;
    @Resource
    protected ConfigContextQueryService configContextQueryService;

    /**
     * 存放支付接口代码
     */
    protected static final Map<String, IPaymentService> payServiceMap = new ConcurrentHashMap<>();

    @PostConstruct
    public void abstractPaymentServiceInit() {
        PayWayCodeEnum payWayCode = this.getPayWayCode();
        IfCodeEnum ifCode = this.getIfCode();
        Assert.notNull(payWayCode, "payWayCode is null, class: " + this.getClass().getName());
        Assert.notNull(ifCode, "ifCode is null, class: " + this.getClass().getName());
        String payServiceKey = getPayServiceKey(ifCode, payWayCode);
        payServiceMap.put(payServiceKey, this);
        log.info("load payService, class: {}", this.getClass().getSimpleName());
    }


    private static String getPayServiceKey(IfCodeEnum ifCodeEnum, PayWayCodeEnum payWayCodeEnum) {
        return ifCodeEnum.getCode().toLowerCase(Locale.ROOT) + "@" + payWayCodeEnum.getCode().toLowerCase(Locale.ROOT);
    }

    /**
     * 获取支付接口
     */
    public static IPaymentService getService(IfCodeEnum ifCodeEnum, PayWayCodeEnum payWayCodeEnum) {
        Assert.notNull(payWayCodeEnum, "payWayCode is null");
        Assert.notNull(ifCodeEnum, "ifCode is null");
        String payServiceKey = getPayServiceKey(ifCodeEnum, payWayCodeEnum);
        // 获取支付接口服务
        return payServiceMap.get(payServiceKey);
    }

    /**
     * 订单分账（一般用作 如微信订单将在下单处做标记）
     */
    protected boolean isDivisionOrder(PayOrder payOrder) {
        //订单分账， 将冻结商户资金。
//        if(payOrder.getDivisionMode() != null && (PayOrder.DIVISION_MODE_AUTO == payOrder.getDivisionMode() || PayOrder.DIVISION_MODE_MANUAL == payOrder.getDivisionMode() )){
//            return true;
//        }
        return false;
    }

    private String getSiteUrlPre() {
        return paySysConfigService.getDBApplicationConfig().getPaySiteUrl() + "/api/" + ServiceCodeCons.PAY_SERVICE;
    }

    protected String getNotifyUrl() {
        return getSiteUrlPre() + "/pay/notify/" + getIfCode().getCode();
    }

    protected String getNotifyUrl(String payOrderNo) {
        return getSiteUrlPre() + "/pay/notify/" + getIfCode().getCode() + "/" + payOrderNo;
    }

    protected String getReturnUrl() {
        return getSiteUrlPre() + "/pay/return/" + getIfCode().getCode();
    }

    protected String getReturnUrl(String payOrderNo) {
        return getSiteUrlPre() + "/pay/return/" + getIfCode().getCode() + "/" + payOrderNo;
    }

    protected String getReturnUrlOnlyJump(String payOrderNo) {
        return getSiteUrlPre() + "/pay/return/" + getIfCode().getCode() + "/" + Cs.PAY_RETURNURL_FIX_ONLY_JUMP_PREFIX + payOrderNo;
    }

}
